#include "selfinfowidget.h"
#include "model/datacenter.h"
#include "utils/widgetuitl.hpp"
#include "debug.h"
#include "toast.h"

#include <QFileDialog>
#include <QGridLayout>
#include <QPushButton>
#include <QTimer>

SelfInfoWidget::SelfInfoWidget(QWidget* parent) : QDialog(parent)
{
    // 1.设置窗口基本属性
    // this->setStyleSheet("QWidget { background-color: white; }");
    this->setFixedSize(500, 250);
    this->setWindowTitle("个人信息");
    this->setWindowIcon(QIcon(":/resource/image/logo.png"));
    // 1-1 窗口关闭时自动销毁对话框对象
    this->setAttribute(Qt::WA_DeleteOnClose);
    // 1-2 把窗口定位到鼠标点击处
    this->move(QCursor::pos());

    // 2.网格布局信息卡片
    layout = new QGridLayout();
    layout->setHorizontalSpacing(10);
    layout->setVerticalSpacing(3);
    layout->setContentsMargins(15, 8, 20, 0);
    layout->setAlignment(Qt::AlignTop);
    this->setLayout(layout);


    ///// 处理修改按钮与验证码按钮居中对齐的
    auto makeButtonCell = [&](QPushButton* button) {
        QWidget* wrapper = new QWidget();
        QHBoxLayout* hlayout = new QHBoxLayout(wrapper);
        hlayout->setContentsMargins(0, 0, 0, 0);
        hlayout->setSpacing(0);
        hlayout->setAlignment(Qt::AlignHCenter);
        hlayout->addWidget(button);
        wrapper->setMinimumWidth(70);
        return wrapper;
    };

    // 3.卡片信息填充
    avatarBtn = createButton({75, 75}, {75, 75}, QIcon(":/resource/image/girl.jpg"));

    idKey = createKeyLabel("序号");
    idVal = createValLabel();

    nameInfo = new InfoLine("昵称");
    descInfo = new InfoLine("签名");
    phoneInfo = new InfoLine("电话");

    // 4.布局管理
    layout->addWidget(avatarBtn, 0, 0, 3, 1);
    layout->addWidget(idKey, 0, 1);
    layout->addWidget(idVal, 0, 2);
    layout->addWidget(nameInfo->key, 1, 1);
    layout->addWidget(nameInfo->val, 1, 2);
    layout->addWidget(makeButtonCell(nameInfo->modifyBtn), 1, 3);
    layout->addWidget(descInfo->key, 2, 1);
    layout->addWidget(descInfo->val, 2, 2);
    layout->addWidget(makeButtonCell(descInfo->modifyBtn), 2, 3);
    layout->addWidget(phoneInfo->key, 3, 1);
    layout->addWidget(phoneInfo->val, 3, 2);
    layout->addWidget(makeButtonCell(phoneInfo->modifyBtn), 3, 3);
    layout->addWidget(phoneInfo->verifyCodeInfo->key, 4, 1);
    layout->addWidget(phoneInfo->verifyCodeInfo->lineEdit, 4, 2);
    layout->addWidget(phoneInfo->verifyCodeInfo->getCodeBtn, 4, 3);

#if TEST_UI
    idVal->setText("191021");
    nameInfo->val->setText("小美");
    descInfo->val->setText("一个清晨, 大雾散去");
    phoneInfo->val->setText("13556492657");
#endif

    // 5.关联按钮信号槽
    initSignals();

    // 6.加载个人信息
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    model::UserInfo* selfInfo = dataCenter->getSelfInfo();
    if(selfInfo) {
        avatarBtn->setIcon(selfInfo->avatar);
        idVal->setText(selfInfo->userId);
        nameInfo->val->setText(selfInfo->nickname);
        descInfo->val->setText(selfInfo->description);
        phoneInfo->val->setText(selfInfo->phone);
    }
}

void SelfInfoWidget::initSignals()
{
    // 关联修改按钮信号槽
    onClickedByModifyBtn(nameInfo, 1, 2);
    onClickedByModifyBtn(descInfo, 2, 2);
    onClickedByModifyBtn(phoneInfo, 3, 2);

    connect(nameInfo->submitBtn, &QPushButton::clicked, this, &SelfInfoWidget::onClickedByNameSubmitBtn);
    connect(descInfo->submitBtn, &QPushButton::clicked, this, &SelfInfoWidget::onClickedByDescSubmitBtn);
    connect(phoneInfo->submitBtn, &QPushButton::clicked, this, &SelfInfoWidget::onClickedByPhoneSubmitBtn);

    connect(avatarBtn,  &QPushButton::clicked, this, &SelfInfoWidget::onClickedByAvatarBtn);
}


void SelfInfoWidget::onClickedByModifyBtn(InfoLine* info, int row, int col)
{
    connect(info->modifyBtn, &QPushButton::clicked, this, [=](){
        // 将原本控件隐藏
        info->val->hide();
        info->modifyBtn->hide();
        layout->removeWidget(info->val);
        layout->removeWidget(info->modifyBtn);
        // 把修改时显示的控件拿出来
        info->lineEdit->show();
        info->submitBtn->show();
        layout->addWidget(info->lineEdit, row, col);
        layout->addWidget(info->submitBtn, row, col + 1);
        info->lineEdit->setText(info->val->text());

        if(info->key->text() == "电话") {
            info->verifyCodeInfo->show();
            // 关联短信验证码信号槽(一定要设置UniqueConnection, 不然多次触发modifyBtn事件, 就会有多执行流一起做倒计时)
            connect(phoneInfo->verifyCodeInfo->getCodeBtn, &QPushButton::clicked, this, &SelfInfoWidget::onClickedBygetCodeBtn, Qt::UniqueConnection);
        }
    });
}

void SelfInfoWidget::onClickedByNameSubmitBtn()
{
    const QString& nickname = nameInfo->lineEdit->text();
    if(nickname.isEmpty()) return;

    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    dataCenter->changeNicknameAsync(nickname);

    connect(dataCenter, &model::DataCenter::changeNicknameDone, this, &SelfInfoWidget::clickNameSubmitBtnDone, Qt::UniqueConnection);
}

void SelfInfoWidget::onClickedByDescSubmitBtn()
{
    const QString& desc = descInfo->lineEdit->text();
    if(desc.isEmpty()) return;

    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    dataCenter->changeDescriptionAsync(desc);

    connect(dataCenter, &model::DataCenter::changeDescriptionDone, this, &SelfInfoWidget::clickDescSubmitBtnDone, Qt::UniqueConnection);
}

void SelfInfoWidget::onClickedByPhoneSubmitBtn()
{
    const QString& phone = phoneInfo->lineEdit->text();
    if(phone.isEmpty()) return;

    model::DataCenter* dataCenter = model::DataCenter::getInstance();

    const QString& verifyCode = phoneInfo->verifyCodeInfo->lineEdit->text();
    if(verifyCode.isEmpty()) {
        Toast::showMessage("验证码为空, 请输入验证码！");
        return;
    }

    QString verifyCodeId = dataCenter->getVerifyCodeId();
    if(verifyCodeId.isEmpty()) {
        Toast::showMessage("操作繁忙, 请稍后重试！");
        return;
    }

    dataCenter->changePhoneAsync(phone, verifyCodeId, verifyCode);

    connect(dataCenter, &model::DataCenter::changePhoneDone, this, &SelfInfoWidget::clickPhoneSubmitBtnDone, Qt::UniqueConnection);
}

void SelfInfoWidget::onClickedByAvatarBtn()
{
    // 选择文件
    QString filter = "Image Files (*.png *.jpg *jpeg)";
    QString imagePath = QFileDialog::getOpenFileName(this, "选择头像", QDir::homePath(), filter);
    if(imagePath.isEmpty()) {
        LOG(LL_INFO, "用户未选择任何头像");
        return;
    }

    // 加载图片数据
    QByteArray imageBytes = utils::FileUtil::loadByteArrayFromFile(imagePath);

    // 发送数据请求
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::changeAvatarDone, this, &SelfInfoWidget::clickAvatarBtnDone);
    dataCenter->changeAvatarAsync(imageBytes);
}


void SelfInfoWidget::onClickedBygetCodeBtn()
{
    const QString& phone = phoneInfo->lineEdit->text();
    if(phone.isEmpty()) {
        Toast::showMessage("手机号为空, 请输入手机号");
        return;
    }

    model::DataCenter* dataCenter = model::DataCenter::getInstance();

    // 清空上次的服务器生成的验证码ID
    dataCenter->resetVerifyCodeId("");

    dataCenter->getVerifyCodeAsync(phone);

    // 低延迟处理, 发送一个网络请求用不到1s, 手动触发定时
    // QMetaObject::invokeMethod(verifyCodeTimer, "timeout");
    utils::TimeUtil::buttonEnableCountDown(verifyCodeTimer, this, phoneInfo->verifyCodeInfo->getCodeBtn, remainTime, 1000, true);

    // 先断开上次发送验证码时与getVerifyCodeDone关联的信号槽(防止连续点击触发多次回调, 作用等同于 Qt::UniqueConnection)
    disconnect(dataCenter, &model::DataCenter::getVerifyCodeDone, this, nullptr);
    connect(dataCenter, &model::DataCenter::getVerifyCodeDone, this, [=]() {
        Toast::showMessage("短信验证码已发送");
    });

    this->phoneToChange = phone;

    phoneInfo->verifyCodeInfo->getCodeBtn->setEnabled(false);
}

void SelfInfoWidget::clickNameSubmitBtnDone()
{
    layout->removeWidget(nameInfo->lineEdit);
    nameInfo->lineEdit->hide();

    layout->addWidget(nameInfo->val, 1, 2);
    nameInfo->val->show();
    nameInfo->val->setText(nameInfo->lineEdit->text());

    layout->removeWidget(nameInfo->submitBtn);
    nameInfo->submitBtn->hide();
    layout->addWidget(nameInfo->modifyBtn, 1, 3);
    nameInfo->modifyBtn->show();
}

void SelfInfoWidget::clickDescSubmitBtnDone()
{
    layout->removeWidget(descInfo->lineEdit);
    descInfo->lineEdit->hide();

    layout->addWidget(descInfo->val, 2, 2);
    descInfo->val->show();
    descInfo->val->setText(descInfo->lineEdit->text());

    layout->removeWidget(descInfo->submitBtn);
    descInfo->submitBtn->hide();
    layout->addWidget(descInfo->modifyBtn, 2, 3);
    descInfo->modifyBtn->show();
}

void SelfInfoWidget::clickPhoneSubmitBtnDone()
{
    // 提交之后, 手动停止这一轮获取验证码的倒计时
    // 如果将倒计时设置为0, 最差情况需要等1s才能更新状态, 延迟太高
    verifyCodeTimer->stop();

    phoneInfo->verifyCodeInfo->hide(/*layout*/);

    layout->removeWidget(phoneInfo->lineEdit);
    phoneInfo->lineEdit->hide();

    layout->addWidget(phoneInfo->val, 3, 2);
    phoneInfo->val->show();
    phoneInfo->val->setText(this->phoneToChange);

    layout->removeWidget(phoneInfo->submitBtn);
    phoneInfo->submitBtn->hide();
    layout->addWidget(phoneInfo->modifyBtn, 3, 3);
    phoneInfo->modifyBtn->show();
}

void SelfInfoWidget::clickAvatarBtnDone()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    avatarBtn->setIcon(dataCenter->getSelfInfo()->avatar);
}


QLabel* SelfInfoWidget::createKeyLabel(const QString& keyString)
{
    QLabel* key = new QLabel();
    key->setFixedSize(labelSize());
    key->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    key->setText(keyString);
    key->setStyleSheet(labelStyle());
    return key;
}

QLabel *SelfInfoWidget::createValLabel()
{
    QLabel* label = new QLabel();
    label->setFixedHeight(labelSize().height());
    label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    return label;
}

QLineEdit* SelfInfoWidget::createLineEdit()
{
    QLineEdit* lineEdit = new QLineEdit();
    lineEdit->setFixedHeight(labelSize().height());
    lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    lineEdit->setStyleSheet(lineEditStyle());
    return lineEdit;
}

QPushButton *SelfInfoWidget::createButton(const QSize& fixedSize, const QSize& iconSize, const QIcon& image)
{
    QPushButton* button = new QPushButton();
    button->setFixedSize(fixedSize);
    button->setIconSize(iconSize);
    if(!image.isNull())
        button->setIcon(image);
    button->setStyleSheet(buttonStyle());
    return button;
}


const QString& SelfInfoWidget::labelStyle() {
    static const QString style = "QLabel { font-size: 14px; font-weight: 800; }";
    return style;
}

const QString& SelfInfoWidget::buttonStyle() {
    static const QString style = "QPushButton { border: none; background-color: transparent; }"
                                 "QPushButton:pressed { background-color: rgb(210, 210, 210); }";
    return style;
}

const QString& SelfInfoWidget::lineEditStyle() {
    static const QString style = "QLineEdit { border: noen; border-radius: 5px; padding-left: 2px; }";
    return style;
}

const QIcon& SelfInfoWidget::modifyIcon() {
    static const QIcon icon(":/resource/image/modify.png");
    return icon;
}

const QIcon& SelfInfoWidget::submitIcon() {
    static const QIcon icon(":/resource/image/submit.png");
    return icon;
}

const QSize &SelfInfoWidget::labelSize() {
    static const QSize size(50, 30);
    return size;
}

const QSize& SelfInfoWidget::btnFixedSize() {
    static const QSize size(25, 25);
    return size;
}

const QSize& SelfInfoWidget::btnIconSize() {
    static const QSize size(20, 20);
    return size;
}

SelfInfoWidget::InfoLine::InfoLine(const QString& keyString)
    : verifyCodeInfo(nullptr)
{
    key = createKeyLabel(keyString);
    val = createValLabel();

    lineEdit = createLineEdit();
    lineEdit->hide();

    modifyBtn = createButton(btnFixedSize(), btnIconSize(), modifyIcon());
    submitBtn = createButton(btnFixedSize(), btnIconSize(), submitIcon());
    submitBtn->hide();

    if(keyString == "电话") {
        verifyCodeInfo = new VerifyCodeInfo();
    }
}

SelfInfoWidget::VerifyCodeInfo::VerifyCodeInfo()
{
    key = createKeyLabel("验证码");
    lineEdit = createLineEdit();

    getCodeBtn = new QPushButton();
    getCodeBtn->setText("获取验证码");
    getCodeBtn->setStyleSheet("QPushButton { border: none; background-color: transparent; }"
                                    "QPushButton:pressed { background-color: rgb(231, 231, 231); }");
    getCodeBtn->setFixedSize(70, labelSize().height());

    this->hide();
}

void SelfInfoWidget::VerifyCodeInfo::show()
{
    key->show();
    lineEdit->show();
    getCodeBtn->show();
}

void SelfInfoWidget::VerifyCodeInfo::hide(/*QGridLayout* layout*/)
{
    key->hide();
    lineEdit->hide();
    getCodeBtn->hide();

    lineEdit->setText("");
    getCodeBtn->setText("获取验证码");
    getCodeBtn->setEnabled(true);
}
